﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization;
using System.Reflection;

namespace PickGold.Base.Remoting
{
	/// <summary>
	/// 方法约束错误
	/// </summary>
	[Serializable]
	[ComVisible(true)]
	[ClassInterface(ClassInterfaceType.None)]
	public class MethodInvalidException : Exception
	{
		private IMethodCallMessage _MethodCallMessage;
		private IMethodReturnMessage _MethodReturnMessage;

		/// <summary>
		/// 使用欲调用消息及实际调用消息初始化 MethodInvalidException 类的新实例。
		/// </summary>
		/// <param name="methodCallMessage">欲调用消息。</param>
		/// <param name="methodReturnMessage">实际调用消息。</param>
		public MethodInvalidException(IMethodCallMessage methodCallMessage, IMethodReturnMessage methodReturnMessage)
			: base()
		{
			this._MethodCallMessage = methodCallMessage;
			this._MethodReturnMessage = methodReturnMessage;
		}

		/// <summary>
		/// 使用欲调用消息、实际调用消息及指定错误描述消息初始化 MethodInvalidException 类的新实例。
		/// </summary>
		/// <param name="methodCallMessage">欲调用消息。</param>
		/// <param name="methodReturnMessage">实际调用消息。</param>
		/// <param name="message">描述错误的消息。</param>
		public MethodInvalidException(IMethodCallMessage methodCallMessage, IMethodReturnMessage methodReturnMessage, string message)
			: base(message)
		{
			this._MethodCallMessage = methodCallMessage;
			this._MethodReturnMessage = methodReturnMessage;
		}

		/// <summary>
		/// 使用欲调用消息、实际调用消息、指定错误描述消息及对作为此异常原因的内部异常的引用来初始化 MethodInvalidException 类的新实例。
		/// </summary>
		/// <param name="methodCallMessage">欲调用消息。</param>
		/// <param name="methodReturnMessage">实际调用消息。</param>
		/// <param name="message">解释异常原因的错误消息。</param>
		/// <param name="innerException">导致当前异常的异常；如果未指定内部异常，则是一个 null 引用（在 Visual Basic 中为 Nothing）。</param>
		public MethodInvalidException(IMethodCallMessage methodCallMessage, IMethodReturnMessage methodReturnMessage, string message, Exception innerException)
			: base(message, innerException)
		{
			this._MethodCallMessage = methodCallMessage;
			this._MethodReturnMessage = methodReturnMessage;
		}

		/// <summary>
		/// 用序列化数据初始化 MethodInvalidException 类的新实例。
		/// </summary>
		/// <param name="info">System.Runtime.Serialization.SerializationInfo，它存有有关所引发异常的序列化的对象数据。</param>
		/// <param name="context">System.Runtime.Serialization.StreamingContext，它包含有关源或目标的上下文信息。</param>
		/// <exception cref="System.ArgumentNullException">info 参数为 null。</exception>
		/// <exception cref="System.Runtime.Serialization.SerializationException">类名为 null 或 System.Exception.HResult 为零 (0)。</exception>
		protected MethodInvalidException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			this._MethodCallMessage = info.GetValue("0", typeof(IMethodCallMessage)) as IMethodCallMessage;
			this._MethodReturnMessage = info.GetValue("1", typeof(IMethodReturnMessage)) as IMethodReturnMessage;
		}

		/// <summary>
		/// 当在派生类中重写时，用关于异常的信息设置 System.Runtime.Serialization.SerializationInfo。
		/// </summary>
		/// <param name="info">System.Runtime.Serialization.SerializationInfo，它存有有关所引发异常的序列化的对象数据。</param>
		/// <param name="context">System.Runtime.Serialization.StreamingContext，它包含有关源或目标的上下文信息。</param>
		/// <exception cref="System.ArgumentNullException">info 参数是 null 引用（Visual Basic 中为 Nothing）。</exception>
		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			base.GetObjectData(info, context);
			info.AddValue("0", this._MethodCallMessage);
			info.AddValue("1", this._MethodReturnMessage);
		}

		/// <summary>
		/// 欲调用的方法
		/// </summary>
		public MethodBase CallMethodBase
		{
			get
			{
				if (this._MethodCallMessage == null)
					return null;

				return this._MethodCallMessage.MethodBase;
			}
		}

		/// <summary>
		/// 欲调用的方法返回类型
		/// </summary>
		public Type CallMethodType
		{
			get
			{
				if (this._MethodCallMessage == null)
					return null;

				if (this._MethodCallMessage.MethodBase == null)
					return null;

				var mi = this._MethodCallMessage.MethodBase as MethodInfo;
				if (mi == null)
					return null;

				return mi.ReturnType;
			}
		}

		/// <summary>
		/// 欲调用的方法名
		/// </summary>
		public string CallMethodName
		{
			get
			{
				if (this._MethodCallMessage == null)
					return null;

				return this._MethodCallMessage.MethodName;
			}
		}

		/// <summary>
		/// 欲调用的方法签名
		/// </summary>
		public object CallMethodSignature
		{
			get
			{
				if (this._MethodCallMessage == null)
					return null;

				return this._MethodCallMessage.MethodSignature;
			}
		}

		/// <summary>
		/// 实际调用的方法
		/// </summary>
		public MethodBase ReturnMethodBase
		{
			get
			{
				if (this._MethodReturnMessage == null)
					return null;

				return this._MethodReturnMessage.MethodBase;
			}
		}

		/// <summary>
		/// 实际调用的方法返回类型
		/// </summary>
		public Type ReturnMethodType
		{
			get
			{
				if (this._MethodReturnMessage == null)
					return null;

				if (this._MethodReturnMessage.MethodBase == null)
					return null;

				var mi = this._MethodReturnMessage.MethodBase as MethodInfo;
				if (mi == null)
					return null;

				return mi.ReturnType;
			}
		}

		/// <summary>
		/// 实际调用的方法名
		/// </summary>
		public string ReturnMethodName
		{
			get
			{
				if (this._MethodReturnMessage == null)
					return null;

				return this._MethodReturnMessage.MethodName;
			}
		}

		/// <summary>
		/// 实际调用的方法签名
		/// </summary>
		public object ReturnMethodSignature
		{
			get
			{
				if (this._MethodReturnMessage == null)
					return null;

				return this._MethodReturnMessage.MethodSignature;
			}
		}

		/// <summary>
		/// 调用结果
		/// </summary>
		public object ReturnValue
		{
			get
			{
				if (this._MethodReturnMessage == null)
					return null;

				return this._MethodReturnMessage.ReturnValue;
			}
		}
	}
}
